﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Gmantis.Controls
{
    public enum UnselectedContentMode
    {
        OutsideVisualTree,
        Collapsed
    }

    [TemplateVisualState(Name = "LeftTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplatePart(Name = "TabPanel", Type = typeof(TabPanel)), 
    TemplatePart(Name = "CloseButton", Type = typeof(Button)), 
    TemplatePart(Name = "SelectedItemContent", Type = typeof(ContentPresenter)), 
    TemplatePart(Name = "PreviousButton", Type = typeof(ButtonBase)), 
    TemplatePart(Name = "NextButton", Type = typeof(ButtonBase)), 
    TemplatePart(Name = "Menu", Type = typeof(Menu)), 
    TemplatePart(Name = "TabStripDropDown", Type = typeof(DropDownButton)), 
    StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(TabItem)), 
    TemplateVisualState(Name = "TopTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "RightTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "BottomTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "Rectangle", GroupName = "ShapeStates"), 
    TemplateVisualState(Name = "Rounded", GroupName = "ShapeStates"), 
    TemplateVisualState(Name = "Sloped", GroupName = "ShapeStates"), 
    TemplateVisualState(Name = "Ribbon", GroupName = "ShapeStates"), 
    TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
    public class TabControl : System.Windows.Controls.ItemsControl
    {
        // Fields
        private int _desiredIndex;
        internal Button _elementCloseButton;
        internal Menu _elementMenu;
        internal ButtonBase _elementNextButton;
        internal ButtonBase _elementPreviousButton;
        internal ContentPresenter _elementSelectedItemContent;
        internal TabPanel _elementTabPanel;
        internal DropDownButton _elementTabStripDropDown;
        internal bool _isLoaded;
        private bool _throwIsMouseOverChanged;
        private int _updating;
        private ReadOnlyCollection<object> _visibleItems;
        public static readonly DependencyProperty CanUserReorderProperty = DependencyProperty.Register("CanUserReorder", typeof(bool), typeof(TabControl), new PropertyMetadata(true));
        internal const string CloseButtonElementName = "CloseButton";
        public static readonly DependencyProperty ContentTemplateProperty = DependencyProperty.Register("ContentTemplate", typeof(DataTemplate), typeof(TabControl), null);
        public static readonly DependencyProperty ContentTemplateSelectorProperty = DependencyProperty.Register("ContentTemplateSelector", typeof(DataTemplateSelector), typeof(TabControl), new PropertyMetadata(null));
        internal static readonly DependencyProperty ForceMouseOverProperty = DependencyProperty.Register("ForceMouseOver", typeof(bool), typeof(TabControl), new PropertyMetadata(new PropertyChangedCallback(TabControl.OnForceMouseOverPropertyChanged)));
        internal int IndexToRecapture;
        internal Action InternalMouseLeftButtonUp;
        public static readonly DependencyProperty IsMouseOverProperty = DependencyProperty.Register("IsMouseOver", typeof(bool), typeof(TabControl), new PropertyMetadata(new PropertyChangedCallback(TabControl.OnIsMouseOverPropertyChanged)));
        internal bool IsPinnedChanging;
        public static readonly DependencyProperty ItemContainerStyleProperty = DependencyProperty.Register("ItemContainerStyle", typeof(Style), typeof(TabControl), new PropertyMetadata(new PropertyChangedCallback(TabControl.OnItemContainerStylePropertyChanged)));
        public static readonly DependencyProperty ItemTemplateSelectorProperty = DependencyProperty.Register("ItemTemplateSelector", typeof(DataTemplateSelector), typeof(TabControl), new PropertyMetadata(null));
        internal const string MenuElementName = "Menu";
        public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(TabControl), null);
        internal const string NextButtonElementName = "NextButton";
        internal int PinnedItemsCount;
        public static readonly DependencyProperty PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(TabControl), null);
        internal const string PreviousButtonElementName = "PreviousButton";
        internal Ranking Ranking;
        internal bool reordering;
        public static readonly DependencyProperty SelectedBackgroundProperty = DependencyProperty.Register("SelectedBackground", typeof(Brush), typeof(TabControl), null);
        public static readonly DependencyProperty SelectedContentProperty = DependencyProperty.Register("SelectedContent", typeof(object), typeof(TabControl), null);
        public static readonly DependencyProperty SelectedIndexProperty = DependencyProperty.Register("SelectedIndex", typeof(int), typeof(TabControl), new PropertyMetadata(-1, new PropertyChangedCallback(TabControl.OnSelectedIndexChanged)));
        internal const string SelectedItemContentElementName = "SelectedItemContent";
        public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(TabControl), new PropertyMetadata(new PropertyChangedCallback(TabControl.OnSelectedItemChanged)));
        private int SelectedRank;
        public static readonly DependencyProperty ShowSingleTabProperty = DependencyProperty.Register("ShowSingleTab", typeof(bool), typeof(TabControl), new PropertyMetadata(true, new PropertyChangedCallback(TabControl.OnShowSingleTabPropertyChanged)));
        internal static readonly DependencyProperty ShowTabsProperty = DependencyProperty.Register("ShowTabs", typeof(bool), typeof(TabControl), new PropertyMetadata(true));
        public static readonly DependencyProperty TabItemCloseProperty = DependencyProperty.Register("TabItemClose", typeof(TabItemCloseOptions), typeof(TabControl), new PropertyMetadata(TabItemCloseOptions.None, new PropertyChangedCallback(TabControl.OnTabItemClosePropertyChanged)));
        public static readonly DependencyProperty TabItemShapeProperty = DependencyProperty.Register("TabItemShape", typeof(TabItemShape), typeof(TabControl), new PropertyMetadata(TabItemShape.Rectangle, new PropertyChangedCallback(TabControl.OnTabItemShapePropertyChanged)));
        internal const string TabPanelElementName = "TabPanel";
        public static readonly DependencyProperty TabStripBackgroundProperty = DependencyProperty.Register("TabStripBackground", typeof(Brush), typeof(TabControl), null);
        internal const string TabStripDropDownElementName = "TabStripDropDown";
        public static readonly DependencyProperty TabStripForegroundProperty = DependencyProperty.Register("TabStripForeground", typeof(Brush), typeof(TabControl), null);
        public static readonly DependencyProperty TabStripHorizontalAlignmentProperty = DependencyProperty.Register("TabStripHorizontalAlignment", typeof(HorizontalAlignment), typeof(TabControl), new PropertyMetadata(HorizontalAlignment.Left));
        public static readonly DependencyProperty TabStripMenuVisibilityProperty = DependencyProperty.Register("TabStripMenuVisibility", typeof(Visibility), typeof(TabControl), new PropertyMetadata(Visibility.Collapsed, new PropertyChangedCallback(TabControl.OnTabStripMenuVisibilityPropertyChanged)));
        public static readonly DependencyProperty TabStripOverlapDirectionProperty = DependencyProperty.Register("TabStripOverlapDirection", typeof(TabPanelOverlapDirection), typeof(TabControl), new PropertyMetadata(TabPanelOverlapDirection.Right));
        public static readonly DependencyProperty TabStripOverlapProperty = DependencyProperty.Register("TabStripOverlap", typeof(int), typeof(TabControl), new PropertyMetadata(2));
        public static readonly DependencyProperty TabStripPlacementProperty = DependencyProperty.Register("TabStripPlacement", typeof(Dock), typeof(TabControl), new PropertyMetadata(Dock.Bottom, new PropertyChangedCallback(TabControl.OnTabStripPlacementPropertyChanged)));
        public static readonly DependencyProperty TabStripVerticalAlignmentProperty = DependencyProperty.Register("TabStripVerticalAlignment", typeof(VerticalAlignment), typeof(TabControl), new PropertyMetadata(VerticalAlignment.Top));
        private object tempItem;
        public static readonly DependencyProperty UnselectedContentModeProperty = DependencyProperty.Register("UnselectedContentMode", typeof(UnselectedContentMode), typeof(TabControl), new PropertyMetadata(UnselectedContentMode.OutsideVisualTree));
        public static readonly DependencyProperty UpdateSourceCollectionProperty = DependencyProperty.Register("UpdateSourceCollection", typeof(bool), typeof(TabControl), new PropertyMetadata(true));

        // Events
        public event EventHandler<PropertyChangedEventArgs<bool>> IsMouseOverChanged;
        public event EventHandler<NotifyCollectionChangedEventArgs> ItemsChanged;
        public event SelectionChangedEventHandler SelectionChanged;
        public event EventHandler<SourcedEventArgs> TabItemClosed;
        public event EventHandler<CancelSourceEventArgs> TabItemClosing;
        public event EventHandler VisibleItemsChanged;

        // Methods
        public TabControl()
        {
            RoutedEventHandler handler = null;
            DependencyPropertyChangedEventHandler handler2 = null;
            this.Ranking = new Ranking();
            this.IndexToRecapture = -1;
            this._desiredIndex = -1;
            this.SelectedRank = -1;
            this.InternalMouseLeftButtonUp = delegate
            {
            };
            this._throwIsMouseOverChanged = true;
            base.DefaultStyleKey = typeof(TabControl);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStateShape(false);
                    this.ChangeVisualStateCommon(false);
                };
            }
            base.Loaded += handler;
            if (handler2 == null)
            {
                handler2 = (s, a) => this.ChangeVisualStateCommon(true);
            }
            base.IsEnabledChanged += handler2;
            base.MouseEnter += new MouseEventHandler(this.Control_MouseEnter);
            base.MouseLeave += new MouseEventHandler(this.Control_MouseLeave);
            this.SetCustomDefaultValues();
        }

        private void _elementSelectedItemContent_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (this._elementSelectedItemContent != null)
            {
                FrameworkElement parent = this._elementSelectedItemContent.Parent as FrameworkElement;
                if (parent != null)
                {
                    RectangleGeometry geometry = new RectangleGeometry
                    {
                        Rect = new Rect(0.0, 0.0, parent.ActualWidth, parent.ActualHeight)
                    };
                    parent.Clip = geometry;
                }
            }
        }

        private void _elementTabStripDropDown_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            this.TabItemFromItem(this.SelectedItem).KeyBoardNavigate(e);
        }

        public void BeginUpdate()
        {
            this._updating++;
        }

        internal void BindInheritedProperties(TabItem tabItem)
        {
            tabItem.SetBinding<TabControl>(Control.BackgroundProperty, this, tc => tc.TabStripBackground);
            tabItem.SetBinding<TabControl>(Control.ForegroundProperty, this, tc => tc.TabStripForeground);
            tabItem.SetBinding<TabControl>(Control.BorderBrushProperty, this, tc => tc.BorderBrush);
            tabItem.SetBinding<TabControl>(Control.BorderThicknessProperty, this, tc => tc.BorderThickness);
            tabItem.SetBinding<TabControl>(TabItem.TabShapeProperty, this, tc => tc.TabItemShape);
            tabItem.SetBinding<TabControl>(TabItem.MouseOverBrushProperty, this, tc => tc.MouseOverBrush);
            tabItem.SetBinding<TabControl>(TabItem.PressedBrushProperty, this, tc => tc.PressedBrush);
            tabItem.SetBinding<TabControl>(TabItem.SelectedBackgroundProperty, this, tc => tc.SelectedBackground);
        }

        private void Control_MouseEnter(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = true;
            }
        }

        private void Control_MouseLeave(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = false;
            }
        }

        internal void ChangeVisibleItems(List<object> visualItems)
        {
            if (!this.CompareList(this._visibleItems, visualItems))
            {
                if (visualItems == null)
                {
                    this._visibleItems = null;
                }
                else
                {
                    this._visibleItems = visualItems.AsReadOnly();
                }
                this._elementTabPanel.OnVisibleItemsChanged();
                this.RaiseVisibleItemsChange();
                this.UpdateCloseButtons();
            }
        }

        protected void ChangeVisualStateCommon(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "Disabled", useTransitions);
            }
            if (base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "MouseOver", useTransitions);
            }
            if ((base.IsEnabled && !this.IsMouseOver) && !this.ForceMouseOver)
            {
                VisualStateHelper.GoToState(this, "Normal", useTransitions);
            }
        }

        protected void ChangeVisualStateShape(bool useTransitions)
        {
            if (this.TabItemShape == TabItemShape.Sloped)
            {
                VisualStateHelper.GoToState(this, "Sloped", useTransitions);
            }
            if (this.TabItemShape == TabItemShape.Ribbon)
            {
                VisualStateHelper.GoToState(this, "Ribbon", useTransitions);
            }
            if (this.TabItemShape == TabItemShape.Rectangle)
            {
                VisualStateHelper.GoToState(this, "Rectangle", useTransitions);
            }
            if (this.TabItemShape == TabItemShape.Rounded)
            {
                VisualStateHelper.GoToState(this, "Rounded", useTransitions);
            }
        }

        protected override void ClearContainerForItemOverride(DependencyObject element, object item)
        {
            base.ClearContainerForItemOverride(element, item);
            TabItem item2 = (TabItem)element;
            item2._tabControlParent = null;
        }

        private void ClearTabPanel()
        {
            if (this._elementTabPanel != null)
            {
                this._elementTabPanel.Children.Clear();
            }
        }

        private bool CompareList(IList<object> list1, IList<object> list2)
        {
            if (((list1 == null) || (list1.Count == 0)) && ((list2 == null) || (list2.Count == 0)))
            {
                return true;
            }
            if ((list1 == null) || (list2 == null))
            {
                return false;
            }
            if (list1.Count != list2.Count)
            {
                return false;
            }
            for (int i = 0; i < list1.Count; i++)
            {
                if (list1[i] != list2[i])
                {
                    return false;
                }
            }
            return true;
        }

        public void EndUpdate()
        {
            this._updating--;
            if (this._updating <= 0)
            {
                this._updating = 0;
                this.OnItemsChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
            }
        }

        internal object FindNextItem(int startRank, int direction)
        {
            int rank = startRank;
            for (int i = 0; i < this.Ranking.RankedCount; i++)
            {
                rank += direction;
                if (rank >= this.Ranking.RankedCount)
                {
                    rank = 0;
                }
                else if (rank < 0)
                {
                    rank = this.Ranking.RankedCount - 1;
                }
                TabItem item = this.TabItemFromIndex(this.Ranking.IndexFromRank(rank));
                if ((item == null) || item.IsReallySelectable)
                {
                    return item;
                }
            }
            return null;
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new TabItem();
        }

        private object GetItemAtIndex(int index)
        {
            if ((index >= 0) && (index < base.Items.Count))
            {
                return base.Items[index];
            }
            return null;
        }

        private DataTemplate GetItemContentDataTemplate(TabItem tabItem, object item)
        {
            object obj2 = (tabItem == item) ? tabItem.Content : item;
            DataTemplate contentTemplate = null;
            if (this.ContentTemplateSelector != null)
            {
                contentTemplate = this.ContentTemplateSelector.SelectTemplate(obj2, tabItem);
            }
            if (this.ContentTemplate != null)
            {
                contentTemplate = this.ContentTemplate;
            }
            if (tabItem == item)
            {
                if (tabItem.ContentTemplateSelector != null)
                {
                    contentTemplate = tabItem.ContentTemplateSelector.SelectTemplate(obj2, tabItem);
                }
                if (tabItem.ContentTemplate != null)
                {
                    contentTemplate = tabItem.ContentTemplate;
                }
            }
            return contentTemplate;
        }

        private DataTemplate GetItemHeaderDataTemplate(TabItem tabItem, object item)
        {
            object obj2 = (tabItem == item) ? tabItem.Header : item;
            DataTemplate itemTemplate = null;
            if (this.ItemTemplateSelector != null)
            {
                itemTemplate = this.ItemTemplateSelector.SelectTemplate(obj2, tabItem);
            }
            if (base.ItemTemplate != null)
            {
                itemTemplate = base.ItemTemplate;
            }
            if (tabItem == item)
            {
                if (tabItem.HeaderTemplateSelector != null)
                {
                    itemTemplate = tabItem.HeaderTemplateSelector.SelectTemplate(obj2, tabItem);
                }
                if (tabItem.HeaderTemplate != null)
                {
                    itemTemplate = tabItem.HeaderTemplate;
                }
            }
            return itemTemplate;
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        internal int IndexFromTabItem(TabItem item)
        {
            if (item == null)
            {
                return -1;
            }
            int index = base.Items.IndexOf(item);
            if (index != -1)
            {
                return index;
            }
            return base.ItemContainerGenerator.IndexFromContainer(item);
        }

        private void InitializeCloseButtonPart()
        {
            this._elementCloseButton.Click += new RoutedEventHandler(this.OnSelectedTabClosed);
        }

        private void InitializeMenuPart()
        {
            this._elementMenu.ItemClick += new EventHandler<SourcedEventArgs>(this.OnMenuItemClicked);
            this.UpdateMenuItems();
        }

        private void InitializeNextButtonPart()
        {
            this._elementNextButton.Click += new RoutedEventHandler(this.OnNextClicked);
        }

        private void InitializePreviousButtonPart()
        {
            this._elementPreviousButton.Click += new RoutedEventHandler(this.OnPreviousClicked);
        }

        private void InitializeSelectedItemContentPart()
        {
            this.UpdateSelectedContent();
        }

        private void InitializeTabPanelPart()
        {
            this._elementTabPanel.TabControl = this;
            this._elementTabPanel.VisibleItemsChanged += new EventHandler(this.UpdateTabPanelScrollButtons);
            this._elementTabPanel.SetBinding(TabPanel.OverlapDirectionProperty, new Binding().From<TabControl>(this, x => x.TabStripOverlapDirection));
            this._elementTabPanel.SetBinding(TabPanel.OverlapProperty, new Binding().From<TabControl>(this, x => x.TabStripOverlap));
        }

        private void InitializeTabStripDropDownPart()
        {
            this._elementTabStripDropDown.KeyDown += new KeyEventHandler(this._elementTabStripDropDown_KeyDown);
        }

        private void InsertIntoTabPanel(int index)
        {
            if (this._elementTabPanel != null)
            {
                IItemContainerGenerator itemContainerGenerator = base.ItemContainerGenerator;
                GeneratorPosition position = base.ItemContainerGenerator.GeneratorPositionFromIndex(index);
                using (itemContainerGenerator.StartAt(position, GeneratorDirection.Forward, true))
                {
                    bool flag;
                    TabItem item = (TabItem)itemContainerGenerator.GenerateNext(out flag);
                    if (!this._elementTabPanel.Children.Contains(item))
                    {
                        this._elementTabPanel.Children.Insert(index, item);
                        itemContainerGenerator.PrepareItemContainer(item);
                    }
                }
            }
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return (item is TabItem);
        }

        private void OnAfterApplyTemplate()
        {
            for (int i = 0; i < base.Items.Count; i++)
            {
                this.InsertIntoTabPanel(i);
            }
            if (this.SelectedIndex != -1)
            {
                this._elementTabPanel.StartRank = this.Ranking.RankFromIndex(this.SelectedIndex);
            }
            this.UpdateSelection();
            this.UpdateSelectedContent();
            this.UpdateMenuItems();
            this.UpdateCloseButtons();
            this.UpdateVisualState();
            this.UpdateTabPanelScrollButtons();
            if (this._elementSelectedItemContent != null)
            {
                this._elementSelectedItemContent.SizeChanged += new SizeChangedEventHandler(this._elementSelectedItemContent_SizeChanged);
            }
        }

        public override void OnApplyTemplate()
        {
            this.OnBeforeApplyTemplate();
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            this._elementTabPanel = this.GetTemplateChild<TabPanel>("TabPanel", true, ref errors);
            if (this._elementTabPanel != null)
            {
                this.InitializeTabPanelPart();
            }
            this._elementCloseButton = this.GetTemplateChild<Button>("CloseButton", true, ref errors);
            if (this._elementCloseButton != null)
            {
                this.InitializeCloseButtonPart();
            }
            this._elementSelectedItemContent = this.GetTemplateChild<ContentPresenter>("SelectedItemContent", true, ref errors);
            if (this._elementSelectedItemContent != null)
            {
                this.InitializeSelectedItemContentPart();
            }
            this._elementPreviousButton = this.GetTemplateChild<ButtonBase>("PreviousButton", true, ref errors);
            if (this._elementPreviousButton != null)
            {
                this.InitializePreviousButtonPart();
            }
            this._elementNextButton = this.GetTemplateChild<ButtonBase>("NextButton", true, ref errors);
            if (this._elementNextButton != null)
            {
                this.InitializeNextButtonPart();
            }
            this._elementMenu = this.GetTemplateChild<Menu>("Menu", false, ref errors);
            if (this._elementMenu != null)
            {
                this.InitializeMenuPart();
            }
            this._elementTabStripDropDown = this.GetTemplateChild<DropDownButton>("TabStripDropDown", false, ref errors);
            if (this._elementTabStripDropDown != null)
            {
                this.InitializeTabStripDropDownPart();
            }
            if (!string.IsNullOrEmpty(errors))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to TabControl.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this.ChangeVisualStateShape(false);
                this.ChangeVisualStateCommon(false);
                this.OnAfterApplyTemplate();
            }
        }

        private void OnBeforeApplyTemplate()
        {
            if (this._elementTabStripDropDown != null)
            {
                this._elementTabStripDropDown.KeyDown -= new KeyEventHandler(this._elementTabStripDropDown_KeyDown);
            }
            if (this._elementMenu != null)
            {
                this._elementMenu.ItemClick -= new EventHandler<SourcedEventArgs>(this.OnMenuItemClicked);
                this._elementMenu.Items.Clear();
            }
            if (this._elementCloseButton != null)
            {
                this._elementCloseButton.Click -= new RoutedEventHandler(this.OnSelectedTabClosed);
            }
            if (this._elementNextButton != null)
            {
                this._elementNextButton.Click -= new RoutedEventHandler(this.OnNextClicked);
            }
            if (this._elementPreviousButton != null)
            {
                this._elementPreviousButton.Click -= new RoutedEventHandler(this.OnNextClicked);
            }
            if (this._elementTabPanel != null)
            {
                this._elementTabPanel.Children.Clear();
                this._elementTabPanel.VisibleItemsChanged -= new EventHandler(this.UpdateTabPanelScrollButtons);
            }
            if (this._elementSelectedItemContent != null)
            {
                this._elementSelectedItemContent.Content = null;
            }
        }

        protected override AutomationPeer OnCreateAutomationPeer()
        {
            return new TabControlAutomationPeer(this);
        }

        private static void OnForceMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as TabControl).ChangeVisualStateCommon(true);
        }

        private static void OnIsMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabControl sender = d as TabControl;
            if ((sender.IsMouseOverChanged != null) && sender._throwIsMouseOverChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsMouseOverChanged(sender, args);
            }
            sender.ChangeVisualStateCommon(true);
        }

        private void OnItemContainerStyleChanged(Style oldValue)
        {
            if (this._elementTabPanel != null)
            {
                foreach (UIElement element in this._elementTabPanel.Children)
                {
                    TabItem tabItem = (TabItem)element;
                    this.SetItemStyle(tabItem);
                }
            }
        }

        private static void OnItemContainerStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabControl control = d as TabControl;
            Style oldValue = (Style)e.OldValue;
            control.OnItemContainerStyleChanged(oldValue);
        }

        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            IList newItems;
            base.OnItemsChanged(e);
            if (this._updating > 0)
            {
                return;
            }
            EventHandler<NotifyCollectionChangedEventArgs> itemsChanged = this.ItemsChanged;
            if (itemsChanged != null)
            {
                itemsChanged(this, e);
            }
            this.UpdateCloseButtons();
            int index = -1;
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    this.Ranking.OnAdded(e.NewStartingIndex, e.NewItems.Count, base.Items.Count);
                    newItems = e.NewItems;
                    break;

                case NotifyCollectionChangedAction.Remove:
                    if (this._elementTabPanel != null)
                    {
                        this._elementTabPanel.SyncMeasureStartRank();
                    }
                    this.Ranking.OnRemoved(e.OldStartingIndex, e.OldItems.Count);
                    for (int i = 0; i < e.OldItems.Count; i++)
                    {
                        this.RemoveFromTabPanel(e.OldStartingIndex + i);
                    }
                    goto Label_0254;

                case NotifyCollectionChangedAction.Reset:
                    this.Ranking.OnReset(base.Items.Count);
                    this.ClearTabPanel();
                    newItems = base.Items;
                    break;

                default:
                    goto Label_0254;
            }
            bool flag = false;
            foreach (object obj2 in newItems)
            {
                TabItem item = this.TabItemFromItem(obj2);
                int num2 = base.Items.IndexOf(obj2);
                this.InsertIntoTabPanel(num2);
                if (!flag)
                {
                    if ((item != null) && item.IsSelected)
                    {
                        index = num2;
                        flag = true;
                    }
                    else if (this.SelectedItem != this.GetItemAtIndex(this.SelectedIndex))
                    {
                        index = base.Items.IndexOf(this.SelectedItem);
                    }
                    else if ((this._desiredIndex < base.Items.Count) && (this._desiredIndex >= 0))
                    {
                        index = this._desiredIndex;
                        this._desiredIndex = -1;
                    }
                }
            }
            if (index == -1)
            {
                foreach (object obj3 in base.Items)
                {
                    TabItem item2 = this.TabItemFromItem(obj3);
                    if ((item2 != null) && item2.IsSelected)
                    {
                        goto Label_0254;
                    }
                }
            }
            if (index == -1)
            {
                index = base.Items.IndexOf(this.SelectedItem);
            }
            if (index == -1)
            {
                index = 0;
            }
            int num3 = this._desiredIndex;
            this.SelectedItem = this.GetItemAtIndex(index);
            this.SelectedIndex = index;
            this._desiredIndex = num3;
        Label_0254:
            this.UpdatePinnedItemsCount();
            this.UpdateSelection();
            this.SelectedRank = this.Ranking.RankFromIndex(this.SelectedIndex);
            this.UpdateShowTabs();
            this.UpdateMenuItems();
            this.UpdateTabPanelScrollButtons(null, EventArgs.Empty);
            this.IndexToRecapture = -1;
        }

        private void OnMenuItemClicked(object sender, SourcedEventArgs e)
        {
            MenuItem source = (MenuItem)e.Source;
            this.SelectedIndex = this.Ranking.IndexFromRank(source.Index);
            this.UpdateTabPanelScrollButtons(null, EventArgs.Empty);
            this.ScrollIntoView(this.SelectedItem);
        }

        private void OnNextClicked(object sender, RoutedEventArgs e)
        {
            this._elementTabPanel.StartRank++;
            this.UpdateTabPanelScrollButtons(null, EventArgs.Empty);
            this._elementTabPanel.InvalidateMeasure();
        }

        private void OnPreviousClicked(object sender, RoutedEventArgs e)
        {
            this._elementTabPanel.StartRank--;
            this.UpdateTabPanelScrollButtons(null, EventArgs.Empty);
            this._elementTabPanel.InvalidateMeasure();
        }

        private static void OnSelectedIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabControl control = (TabControl)d;
            int oldValue = (int)e.OldValue;
            control.TabItemContentLostFocus(oldValue);
            control.SelectedRank = control.Ranking.RankFromIndex(control.SelectedIndex);
            if (control.SelectedIndex == -1)
            {
                control.SelectedItem = null;
                control._desiredIndex = -1;
            }
            else if (control.SelectedIndex < -1)
            {
                control.SelectedIndex = -1;
            }
            else if (control.SelectedIndex >= control.Items.Count)
            {
                int selectedIndex = control.SelectedIndex;
                control.SelectedIndex = -1;
                control._desiredIndex = selectedIndex;
            }
            else
            {
                if (control.IndexFromTabItem(control.TabItemFromItem(control.Items[control.SelectedIndex])) != control.SelectedIndex)
                {
                    control.tempItem = control.TabItemFromIndex(control.SelectedIndex);
                }
                control.SelectedItem = control.Items[control.SelectedIndex];
                control._desiredIndex = -1;
            }
            TabItem item = control.TabItemFromItem(control.SelectedItem);
            if ((item == null) || item.IsReallySelectable)
            {
                control.ScrollIntoView(control.SelectedItem);
            }
            else
            {
                control.SelectedIndex = oldValue;
            }
        }

        private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabItem tempItem;
            TabControl control = (TabControl)d;
            if (control.tempItem != null)
            {
                tempItem = control.tempItem as TabItem;
                control.tempItem = null;
            }
            else
            {
                tempItem = control.TabItemFromItem(e.NewValue);
            }
            int num = (e.NewValue == null) ? -1 : ((tempItem == null) ? control.Items.IndexOf(e.NewValue) : control.IndexFromTabItem(tempItem));
            if ((e.NewValue != null) && ((num == -1) || ((tempItem != null) && !tempItem.IsReallySelectable)))
            {
                control.SelectedItem = e.OldValue;
            }
            else
            {
                control.SelectedIndex = num;
                control.UpdateSelectedContent();
                control.UpdateIsSelected();
                if (!control.IsPinnedChanging)
                {
                    control.OnSelectionChanged(e.OldValue);
                }
                if (control._elementTabPanel != null)
                {
                    control._elementTabPanel.InvalidateArrange();
                }
            }
        }

        private void OnSelectedTabClosed(object sender, RoutedEventArgs e)
        {
            if (this.SelectedIndex != -1)
            {
                this.OnTabItemClosing(this.SelectedIndex);
            }
        }

        internal void OnSelectionChanged(object oldItem)
        {
            if ((this.SelectionChanged != null) && !this.reordering)
            {
                object[] removedItems = (oldItem == null) ? new object[0] : new object[] { oldItem };
                object[] addedItems = (this.SelectedItem == null) ? new object[0] : new object[] { this.SelectedItem };
                SelectionChangedEventArgs e = new SelectionChangedEventArgs(removedItems, addedItems);
                this.SelectionChanged(this, e);
            }
        }

        private void OnShowSingleTabChanged(bool oldValue)
        {
            this.UpdateShowTabs();
        }

        private static void OnShowSingleTabPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabControl control = d as TabControl;
            bool oldValue = (bool)e.OldValue;
            control.OnShowSingleTabChanged(oldValue);
        }

        private void OnTabItemCloseChanged(TabItemCloseOptions oldValue)
        {
            this.UpdateCloseButtons();
        }

        private static void OnTabItemClosePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabControl control = d as TabControl;
            TabItemCloseOptions oldValue = (TabItemCloseOptions)e.OldValue;
            control.OnTabItemCloseChanged(oldValue);
        }

        internal virtual void OnTabItemClosing(int index)
        {
            if (this.Ranking.RankFromIndex(index) != -1)
            {
                TabItem item = this.TabItemFromIndex(index);
                if ((item == null) || item.CanUserClose)
                {
                    if (((index == (base.Items.Count - 1)) && (index > 0)) && item.IsSelected)
                    {
                        this.TabItemFromIndex(index - 1).Focus();
                    }
                    this.UpdateCloseButtons();
                    CancelSourceEventArgs e = new CancelSourceEventArgs
                    {
                        Cancel = false,
                        Source = item
                    };
                    if (this.TabItemClosing != null)
                    {
                        this.TabItemClosing(this, e);
                    }
                    if (!e.Cancel)
                    {
                        IList list = this.SourceList();
                        if (list != null)
                        {
                            list.RemoveAt(index);
                        }
                        else
                        {
                            this.VirtualRemove(index);
                            this.UpdateMenuItems();
                            this._elementTabPanel.InvalidateMeasure();
                        }
                        if (this.TabItemClosed != null)
                        {
                            SourcedEventArgs args2 = new SourcedEventArgs
                            {
                                Source = item
                            };
                            this.TabItemClosed(this, args2);
                            this._elementTabPanel.InvalidateMeasure();
                        }
                    }
                }
            }
        }

        private void OnTabItemShapeChanged(TabItemShape oldValue)
        {
        }

        private static void OnTabItemShapePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabControl control = d as TabControl;
            TabItemShape oldValue = (TabItemShape)e.OldValue;
            control.OnTabItemShapeChanged(oldValue);
            control.ChangeVisualStateShape(true);
        }

        private void OnTabStripMenuVisibilityChanged(Visibility old)
        {
            this.UpdateMenuItems();
        }

        private static void OnTabStripMenuVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabControl control = d as TabControl;
            Visibility oldValue = (Visibility)e.OldValue;
            control.OnTabStripMenuVisibilityChanged(oldValue);
        }

        private void OnTabStripPlacementChanged(Dock oldValue)
        {
            this.UpdateVisualState();
        }

        private static void OnTabStripPlacementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabControl control = d as TabControl;
            Dock oldValue = (Dock)e.OldValue;
            control.OnTabStripPlacementChanged(oldValue);
        }

        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            TabItem tabItem = (TabItem)element;
            this.SetItemStyle(tabItem);
            Binding parentBinding = null;
            if (tabItem.ReadLocalValue(ContentControl.ContentProperty) is BindingExpressionBase)
            {
                parentBinding = ((BindingExpression)tabItem.ReadLocalValue(ContentControl.ContentProperty)).ParentBinding;
            }
            base.PrepareContainerForItemOverride(element, item);
            if (parentBinding != null)
            {
                tabItem.SetBinding(ContentControl.ContentProperty, parentBinding);
                parentBinding = null;
            }
            int index = this.IndexFromTabItem(tabItem);
            tabItem._tabControlParent = this;
            this.BindInheritedProperties(tabItem);
            tabItem.UpdateVisualState();
            tabItem.UpdateCloseButton();
            if ((item != tabItem) && (tabItem.Header == null))
            {
                tabItem.Header = item;
            }
            tabItem.HeaderTemplate = this.GetItemHeaderDataTemplate(tabItem, item);
            tabItem.ContentTemplate = this.GetItemContentDataTemplate(tabItem, item);
            this.UpdateSelectedContent();
            tabItem.IsSelected = index == this.SelectedIndex;
            if (this._elementMenu != null)
            {
                int num2 = this.Ranking.RankFromIndex(index);
                if ((num2 != -1) && (num2 < this._elementMenu.Items.Count))
                {
                    (this._elementMenu.Items[num2] as MenuItem).FontWeight = (index == this.SelectedIndex) ? FontWeights.Bold : FontWeights.Normal;
                }
            }
            if (index == this.IndexToRecapture)
            {
                base.ReleaseMouseCapture();
                if (tabItem.TryCaptureMouse())
                {
                    tabItem.MouseMove += new MouseEventHandler(tabItem.TabItem_MouseMove);
                    tabItem.LostMouseCapture += new MouseEventHandler(tabItem.TabItem_LostMouseCapture);
                    tabItem.MouseLeftButtonUp += new MouseButtonEventHandler(tabItem.TabItem_MouseLeftButtonUp);
                }
            }
            this.IndexToRecapture = -1;
        }

        private void RaiseVisibleItemsChange()
        {
            if (this.VisibleItemsChanged != null)
            {
                this.VisibleItemsChanged(this, new EventArgs());
            }
        }

        private void RemoveFromTabPanel(int index)
        {
            if (this._elementTabPanel != null)
            {
                this._elementTabPanel.Children.RemoveAt(index);
            }
        }

        public void ScrollIntoView(object item)
        {
            if (this._elementTabPanel != null)
            {
                int index = base.Items.IndexOf(item);
                if (index != -1)
                {
                    int num2 = this.Ranking.RankFromIndex(index);
                    if ((num2 < this._elementTabPanel.StartRank) || ((this._elementTabPanel.StartRank + this._elementTabPanel.VisibleItemsCount) <= num2))
                    {
                        this._elementTabPanel.StartRank = num2;
                    }
                }
            }
        }

        private void SetCustomDefaultValues()
        {
            EventHandler handler = null;
            base.IsTabStop = false;
            base.MouseLeftButtonUp += delegate(object param0, MouseButtonEventArgs param1)
            {
                this.InternalMouseLeftButtonUp();
                base.ReleaseMouseCapture();
                this.IndexToRecapture = -1;
            };
            if (DesignerProperties.IsInDesignTool)
            {
                if (handler == null)
                {
                    handler = (param0, param1) => this.UpdateShowTabs();
                }
                base.LayoutUpdated += handler;
            }
        }

        internal void SetItemStyle(TabItem tabItem)
        {
            if ((tabItem.ReadLocalValue(FrameworkElement.StyleProperty) == DependencyProperty.UnsetValue) || tabItem.IsStyleSetByTabControl)
            {
                if (tabItem.Style != this.ItemContainerStyle)
                {
                    if (this.ItemContainerStyle == null)
                    {
                        tabItem.ClearValue(FrameworkElement.StyleProperty);
                    }
                    else
                    {
                        tabItem.Style = this.ItemContainerStyle;
                    }
                }
                tabItem.IsStyleSetByTabControl = true;
            }
        }

        internal IList SourceList()
        {
            if (!this.UpdateSourceCollection)
            {
                return null;
            }
            if (base.ItemsSource == null)
            {
                return base.Items;
            }
            IList itemsSource = base.ItemsSource as IList;
            if (itemsSource == null)
            {
                return null;
            }
            if (!(itemsSource is INotifyCollectionChanged))
            {
                return null;
            }
            if (itemsSource.IsFixedSize)
            {
                return null;
            }
            if (itemsSource.IsReadOnly)
            {
                return null;
            }
            return itemsSource;
        }

        private void TabItemContentLostFocus(int index)
        {
            if ((!PlatformIndependent.IsInDesignMode(this) && (index > -1)) && (index < base.Items.Count))
            {
                TabItem item = this.TabItemFromIndex(index);
                for (DependencyObject obj2 = FocusManager.GetFocusedElement() as DependencyObject; obj2 != null; obj2 = obj2.GetVisualOrLogicalParent())
                {
                    if ((item != null) && (((obj2 == item.Content) || (obj2 == item)) || (obj2 == this)))
                    {
                        item.Focus();
                    }
                }
            }
        }

        internal TabItem TabItemFromIndex(int index)
        {
            TabItem itemAtIndex = this.GetItemAtIndex(index) as TabItem;
            if (itemAtIndex != null)
            {
                return itemAtIndex;
            }
            return (TabItem)base.ItemContainerGenerator.ContainerFromIndex(index);
        }

        internal TabItem TabItemFromItem(object item)
        {
            TabItem item2 = item as TabItem;
            if (item2 != null)
            {
                return item2;
            }
            return (TabItem)base.ItemContainerGenerator.ContainerFromItem(item);
        }

        private void UpdateCloseButtons()
        {
            if (this._isLoaded)
            {
                this._elementCloseButton.Visibility = ((this.TabItemClose == TabItemCloseOptions.GlobalClose) && (((this.VisibleItems != null) ? this.VisibleItems.Count : base.Items.Count) > 0)).ToVisibility();
                for (int i = 0; i < base.Items.Count; i++)
                {
                    TabItem item = this.TabItemFromIndex(i);
                    if (item != null)
                    {
                        item.UpdateCloseButton();
                    }
                }
            }
        }

        private void UpdateIsSelected()
        {
            for (int i = 0; i < base.Items.Count; i++)
            {
                TabItem item = this.TabItemFromIndex(i);
                if (item != null)
                {
                    item.IsSelected = i == this.SelectedIndex;
                    if (this._elementMenu != null)
                    {
                        int num2 = this.Ranking.RankFromIndex(i);
                        if ((num2 != -1) && (num2 < this._elementMenu.Items.Count))
                        {
                            (this._elementMenu.Items[num2] as MenuItem).FontWeight = (i == this.SelectedIndex) ? FontWeights.Bold : FontWeights.Normal;
                        }
                    }
                }
            }
        }

        internal void UpdateMenuItems()
        {
            if (this._elementMenu != null)
            {
                this._elementMenu.Items.Clear();
                if (this.TabStripMenuVisibility != Visibility.Collapsed)
                {
                    for (int i = 0; i < this.Ranking.RankedCount; i++)
                    {
                        int index = this.Ranking.IndexFromRank(i);
                        MenuItem item = new MenuItem
                        {
                            FontWeight = (index == this.SelectedIndex) ? FontWeights.Bold : FontWeights.Normal
                        };
                        ContentPresenter presenter = new ContentPresenter();
                        item.Header = presenter;
                        this._elementMenu.Items.Add(item);
                        TabItem source = this.TabItemFromIndex(index);
                        if (source == null)
                        {
                            presenter.Content = base.Items[index];
                            presenter.SetBinding(ContentPresenter.ContentTemplateProperty, new Binding().From<TabControl>(this, x => x.ItemTemplate));
                        }
                        else
                        {
                            item.Visibility = source.IsReallySelectable.ToVisibility();
                            if (source.Header is TextBlock)
                            {
                                TextBlock header = source.Header as TextBlock;
                                presenter.SetBinding(ContentPresenter.ContentProperty, new Binding().From<TextBlock>(header, x => x.Text));
                            }
                            else
                            {
                                presenter.SetBinding(ContentPresenter.ContentProperty, new Binding().From<TabItem>(source, x => x.Header));
                                presenter.SetBinding(ContentPresenter.ContentTemplateProperty, new Binding().From<TabItem>(source, x => x.HeaderTemplate));
                            }
                        }
                    }
                }
            }
        }

        internal void UpdatePinnedItemsCount()
        {
            this.PinnedItemsCount = 0;
            for (int i = 0; i < base.Items.Count; i++)
            {
                if (this.Ranking.RankFromIndex(i) != -1)
                {
                    TabItem item = null;
                    if (base.Items[i] is TabItem)
                    {
                        item = base.Items[i] as TabItem;
                    }
                    else
                    {
                        item = this.TabItemFromIndex(i);
                    }
                    if ((item != null) && (item.ActualPinMode == PinMode.Pinned))
                    {
                        this.PinnedItemsCount++;
                    }
                }
            }
        }

        internal void UpdateSelectedContent()
        {
            object content = null;
            DataTemplate contentTemplate = null;
            if (this.SelectedIndex == -1)
            {
                content = null;
                contentTemplate = null;
            }
            else
            {
                TabItem selectedItem = this.SelectedItem as TabItem;
                if (selectedItem == null)
                {
                    selectedItem = this.TabItemFromItem(this.SelectedItem);
                }
                if (selectedItem != null)
                {
                    content = selectedItem.Content;
                    contentTemplate = selectedItem.ContentTemplate;
                }
            }
            this.SelectedContent = content;
            if (this._elementSelectedItemContent != null)
            {
                switch (this.UnselectedContentMode)
                {
                    case UnselectedContentMode.OutsideVisualTree:
                        this._elementSelectedItemContent.Content = content;
                        this._elementSelectedItemContent.ContentTemplate = contentTemplate;
                        return;

                    case UnselectedContentMode.Collapsed:
                        {
                            ContentGrid grid = this._elementSelectedItemContent.Content as ContentGrid;
                            if (grid == null)
                            {
                                grid = new ContentGrid();
                                this._elementSelectedItemContent.Content = grid;
                            }
                            bool flag = false;
                            int index = 0;
                            while (index < grid.Children.Count)
                            {
                                ItemPresenter presenter = (ItemPresenter)grid.Children[index];
                                if (!base.Items.Contains(presenter.Item))
                                {
                                    presenter.Content = null;
                                    grid.Children.RemoveAt(index);
                                }
                                else
                                {
                                    if (presenter.Item == this.SelectedItem)
                                    {
                                        presenter.Visibility = Visibility.Visible;
                                        presenter.Content = content;
                                        presenter.ContentTemplate = contentTemplate;
                                        flag = true;
                                        index++;
                                        continue;
                                    }
                                    presenter.Visibility = Visibility.Collapsed;
                                    index++;
                                }
                            }
                            if (!flag && (this.SelectedItem != null))
                            {
                                ItemPresenter presenter2 = new ItemPresenter
                                {
                                    Item = this.SelectedItem,
                                    Content = content,
                                    ContentTemplate = contentTemplate
                                };
                                grid.Children.Add(presenter2);
                            }
                            break;
                        }
                    default:
                        return;
                }
            }
        }

        internal void UpdateSelection()
        {
            int num = this._desiredIndex;
            try
            {
                int index = this.IndexFromTabItem(this.TabItemFromItem(this.SelectedItem));
                if (index != -1)
                {
                    if (this.Ranking.RankFromIndex(index) != -1)
                    {
                        TabItem item = this.TabItemFromIndex(index);
                        if ((item == null) || item.IsReallySelectable)
                        {
                            this.SelectedIndex = index;
                            return;
                        }
                    }
                }
                else
                {
                    for (int k = 0; k < base.Items.Count; k++)
                    {
                        TabItem item2 = base.Items[k] as TabItem;
                        if ((item2 != null) && item2.IsSelected)
                        {
                            this.SelectedIndex = k;
                            this.SelectedItem = item2;
                            return;
                        }
                    }
                }
                this.SelectedRank = Math.Max(0, Math.Min(this.Ranking.RankedCount - 1, this.SelectedRank));
                for (int i = this.SelectedRank; i < this.Ranking.RankedCount; i++)
                {
                    index = this.Ranking.IndexFromRank(i);
                    TabItem item3 = this.TabItemFromIndex(index);
                    if ((item3 == null) || item3.IsReallySelectable)
                    {
                        this.SelectedIndex = index;
                        this.SelectedItem = base.Items[index];
                        return;
                    }
                }
                for (int j = this.SelectedRank; j > 0; j--)
                {
                    index = this.Ranking.IndexFromRank(j - 1);
                    TabItem item4 = this.TabItemFromIndex(index);
                    if ((item4 == null) || item4.IsReallySelectable)
                    {
                        this.SelectedIndex = index;
                        this.SelectedItem = base.Items[index];
                        return;
                    }
                }
                this.SelectedIndex = -1;
            }
            finally
            {
                this._desiredIndex = num;
            }
        }

        private void UpdateShowTabs()
        {
            if (!DesignerProperties.IsInDesignTool || this._isLoaded)
            {
                this.ShowTabs = this.ShowSingleTab || (base.Items.Count > 1);
            }
        }

        private void UpdateTabPanelScrollButtons()
        {
            if (this._elementTabPanel != null)
            {
                if (this._elementTabPanel.VisibleItemsCount < this.Ranking.RankedCount)
                {
                    if (this._elementTabPanel.StartRank > 0)
                    {
                        this._elementPreviousButton.Visibility = Visibility.Visible;
                        this._elementPreviousButton.IsEnabled = true;
                    }
                    else
                    {
                        this._elementPreviousButton.Visibility = Visibility.Collapsed;
                        this._elementPreviousButton.IsEnabled = false;
                    }
                    if ((this._elementTabPanel.StartRank + this._elementTabPanel.VisibleItemsCount) < this.Ranking.RankedCount)
                    {
                        this._elementNextButton.Visibility = Visibility.Visible;
                        this._elementNextButton.IsEnabled = true;
                    }
                    else
                    {
                        this._elementNextButton.Visibility = Visibility.Collapsed;
                        this._elementNextButton.IsEnabled = false;
                    }
                }
                else
                {
                    this._elementPreviousButton.Visibility = Visibility.Collapsed;
                    this._elementNextButton.Visibility = Visibility.Collapsed;
                    this._elementPreviousButton.IsEnabled = false;
                    this._elementNextButton.IsEnabled = false;
                }
            }
        }

        private void UpdateTabPanelScrollButtons(object sender, EventArgs e)
        {
            this.UpdateTabPanelScrollButtons();
        }

        internal virtual void UpdateVisualState()
        {
            VisualStateHelper.GoToState(this, this.ActualTabStripPlacement + "TabStripPlacement", true);
            if (this._elementTabPanel != null)
            {
                foreach (UIElement element in this._elementTabPanel.Children)
                {
                    TabItem item = element as TabItem;
                    if (item != null)
                    {
                        item.UpdateVisualState();
                    }
                }
            }
        }

        internal void VirtualMove(int oldIndex, int newIndex)
        {
            this.Ranking.VirtualMove(oldIndex, newIndex);
            this.SelectedRank = this.Ranking.RankFromIndex(this.SelectedIndex);
        }

        internal void VirtualRemove(int index)
        {
            this.Ranking.VirtualRemove(index);
            int num = this.Ranking.RankFromIndex(this.SelectedIndex);
            if (num != -1)
            {
                this.SelectedRank = num;
            }
            this.UpdateSelection();
            this.UpdatePinnedItemsCount();
            if (this._elementTabPanel != null)
            {
                this._elementTabPanel.SyncMeasureStartRank();
            }
        }

        // Properties
        internal virtual Dock ActualTabStripPlacement
        {
            get
            {
                return this.TabStripPlacement;
            }
        }

        public bool CanUserReorder
        {
            get { return (bool)GetValue(CanUserReorderProperty); }
            set { SetValue(CanUserReorderProperty, value); }
        }

        public DataTemplate ContentTemplate
        {
            get { return (DataTemplate)GetValue(ContentTemplateProperty); }
            set { SetValue(ContentTemplateProperty, value); }
        }

        public DataTemplateSelector ContentTemplateSelector
        {
            get { return (DataTemplateSelector)GetValue(ContentTemplateSelectorProperty); }
            set { SetValue(ContentTemplateSelectorProperty, value); }
        }

        internal bool ForceMouseOver
        {
            get { return (bool)GetValue(ForceMouseOverProperty); }
            set { SetValue(ForceMouseOverProperty, value); }
        }

        public bool IsMouseOver
        {
            get { return (bool)GetValue(IsMouseOverProperty); }
            internal set { SetValue(IsMouseOverProperty, value); }
        }

        public Style ItemContainerStyle
        {
            get { return (Style)GetValue(ItemContainerStyleProperty); }
            set { SetValue(ItemContainerStyleProperty, value); }
        }

        public DataTemplateSelector ItemTemplateSelector
        {
            get { return (DataTemplateSelector)GetValue(ItemTemplateSelectorProperty); }
            set { SetValue(ItemTemplateSelectorProperty, value); }
        }

        public Brush MouseOverBrush
        {
            get { return (Brush)GetValue(MouseOverBrushProperty); }
            set { SetValue(MouseOverBrushProperty, value); }
        }

        public Brush PressedBrush
        {
            get { return (Brush)GetValue(PressedBrushProperty); }
            set { SetValue(PressedBrushProperty, value); }
        }

        public Brush SelectedBackground
        {
            get { return (Brush)GetValue(SelectedBackgroundProperty); }
            set { SetValue(SelectedBackgroundProperty, value); }
        }

        public object SelectedContent
        {
            get { return GetValue(SelectedContentProperty); }
            internal set { SetValue(SelectedContentProperty, value); }
        }

        public int SelectedIndex
        {
            get { return (int)GetValue(SelectedIndexProperty); }
            set { SetValue(SelectedIndexProperty, value); }
        }

        public object SelectedItem
        {
            get { return GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }

        public bool ShowSingleTab
        {
            get { return (bool)GetValue(ShowSingleTabProperty); }
            set { SetValue(ShowSingleTabProperty, value); }
        }

        internal bool ShowTabs
        {
            get { return (bool)GetValue(ShowTabsProperty); }
            set { SetValue(ShowTabsProperty, value); }
        }

        public TabItemCloseOptions TabItemClose
        {
            get { return (TabItemCloseOptions)GetValue(TabItemCloseProperty); }
            set { SetValue(TabItemCloseProperty, value); }
        }

        public TabItemShape TabItemShape
        {
            get { return (TabItemShape)GetValue(TabItemShapeProperty); }
            set { SetValue(TabItemShapeProperty, value); }
        }

        public Brush TabStripBackground
        {
            get { return (Brush)GetValue(TabStripBackgroundProperty); }
            set { SetValue(TabStripBackgroundProperty, value); }
        }

        public Brush TabStripForeground
        {
            get { return (Brush)GetValue(TabStripForegroundProperty); }
            set { SetValue(TabStripForegroundProperty, value); }
        }

        public HorizontalAlignment TabStripHorizontalAlignment
        {
            get { return (HorizontalAlignment)GetValue(TabStripHorizontalAlignmentProperty); }
            set { SetValue(TabStripHorizontalAlignmentProperty, value); }
        }

        public Visibility TabStripMenuVisibility
        {
            get { return (Visibility)GetValue(TabStripMenuVisibilityProperty); }
            set { SetValue(TabStripMenuVisibilityProperty, value); }
        }

        public int TabStripOverlap
        {
            get { return (int)GetValue(TabStripOverlapProperty); }
            set { SetValue(TabStripOverlapProperty, value); }
        }

        public TabPanelOverlapDirection TabStripOverlapDirection
        {
            get { return (TabPanelOverlapDirection)GetValue(TabStripOverlapDirectionProperty); }
            set { SetValue(TabStripOverlapDirectionProperty, value); }
        }

        public Dock TabStripPlacement
        {
            get { return (Dock)GetValue(TabStripPlacementProperty); }
            set { SetValue(TabStripPlacementProperty, value); }
        }

        public VerticalAlignment TabStripVerticalAlignment
        {
            get { return (VerticalAlignment)GetValue(TabStripVerticalAlignmentProperty); }
            set { SetValue(TabStripVerticalAlignmentProperty, value); }
        }

        public UnselectedContentMode UnselectedContentMode
        {
            get { return (UnselectedContentMode)GetValue(UnselectedContentModeProperty); }
            set { SetValue(UnselectedContentModeProperty, value); }
        }

        public bool UpdateSourceCollection
        {
            get { return (bool)GetValue(UpdateSourceCollectionProperty); }
            set { SetValue(UpdateSourceCollectionProperty, value); }
        }

        public ReadOnlyCollection<object> VisibleItems
        {
            get { return this._visibleItems; }
        }

        // Nested Types
        private class ContentGrid : Grid
        {
        }

        private class ItemPresenter : ContentPresenter
        {
            // Fields
            public object Item;
        }
    }
}
